/**
 * 全局错误处理工具
 * 用于捕获和处理各种错误，防止应用卡死
 */

class ErrorHandler {
	constructor() {
		this.errorCount = 0;
		this.maxErrors = 10; // 最大错误数量
		this.errorWindow = 60000; // 错误窗口时间（1分钟）
		this.lastErrorTime = 0;
		this.isHandling = false;
	}

	/**
	 * 初始化错误处理
	 */
	init() {
		// 捕获全局错误
		uni.onError((error) => {
			this.handleError('Global Error', error);
		});

		// 捕获未处理的Promise拒绝
		uni.onUnhandledRejection((event) => {
			this.handleError('Unhandled Promise Rejection', event.reason);
		});

	
	}

	/**
	 * 处理错误
	 * @param {string} type 错误类型
	 * @param {Error|string} error 错误信息
	 */
	handleError(type, error) {
		// 防止重复处理
		if (this.isHandling) {
			return;
		}

		this.isHandling = true;

		try {
			const now = Date.now();
			
			// 检查错误频率
			if (now - this.lastErrorTime > this.errorWindow) {
				this.errorCount = 0;
			}
			
			this.errorCount++;
			this.lastErrorTime = now;

			// 记录错误
			console.error(`[${type}]`, error);

			// 如果错误过多，采取保护措施
			if (this.errorCount > this.maxErrors) {
				this.handleTooManyErrors();
				return;
			}

			// 根据错误类型采取不同处理策略
			switch (type) {
				case 'Network Error':
					this.handleNetworkError(error);
					break;
				case 'WebSocket Error':
					this.handleWebSocketError(error);
					break;
				case 'Timer Error':
					this.handleTimerError(error);
					break;
				case 'Memory Error':
					this.handleMemoryError(error);
					break;
				default:
					this.handleGeneralError(error);
			}

		} catch (handlingError) {
			console.error('错误处理失败:', handlingError);
		} finally {
			this.isHandling = false;
		}
	}

	/**
	 * 处理网络错误
	 */
	handleNetworkError(error) {
		console.warn('检测到网络错误，可能需要重试');
		// 可以在这里添加网络重试逻辑
	}

	/**
	 * 处理WebSocket错误
	 */
	handleWebSocketError(error) {
		console.warn('检测到WebSocket错误，可能需要重新连接');
		// 可以在这里添加WebSocket重连逻辑
		// 导入WebSocket工具并尝试重连
		try {
			const { forceReconnect } = require('./webSokent.js');
			if (forceReconnect) {
				forceReconnect();
			}
		} catch (e) {
			console.error('WebSocket重连失败:', e);
		}
	}

	/**
	 * 处理定时器错误
	 */
	handleTimerError(error) {
		console.warn('检测到定时器错误，清理相关资源');
		// 可以在这里添加定时器清理逻辑
	}

	/**
	 * 处理内存错误
	 */
	handleMemoryError(error) {
		console.warn('检测到内存错误，清理缓存');
		// 可以在这里添加内存清理逻辑
	}

	/**
	 * 处理一般错误
	 */
	handleGeneralError(error) {
		console.warn('检测到一般错误');
		// 可以在这里添加一般错误处理逻辑
	}

	/**
	 * 处理API错误，提取详细的错误信息
	 * @param {Error} error - 错误对象
	 * @param {string} defaultMessage - 默认错误信息
	 * @returns {string} 处理后的错误信息
	 */
	handleApiError(error, defaultMessage = '操作失败') {
		let errorMessage = defaultMessage;
		
		// 如果是响应错误，尝试获取详细错误信息
		if (error.response && error.response.data) {
			const errorData = error.response.data;
			if (errorData.message) {
				errorMessage = errorData.message;
			} else if (errorData.code === 400) {
				// 处理业务错误
				errorMessage = errorData.message || '请求参数错误';
			} else if (errorData.code === 401) {
				errorMessage = '登录已过期，请重新登录';
			} else if (errorData.code === 403) {
				errorMessage = '没有权限执行此操作';
			} else if (errorData.code === 404) {
				errorMessage = '请求的资源不存在';
			} else if (errorData.code === 500) {
				errorMessage = '服务器内部错误';
			}
		} else if (error.message) {
			errorMessage = error.message;
		}
		
		return errorMessage;
	}

	/**
	 * 显示API错误提示
	 * @param {Error} error - 错误对象
	 * @param {string} defaultMessage - 默认错误信息
	 */
	showApiError(error, defaultMessage = '操作失败') {
		const errorMessage = this.handleApiError(error, defaultMessage);
		uni.showToast({
			title: errorMessage,
			icon: 'none',
			duration: 2000
		});
	}

	/**
	 * 处理过多错误
	 */
	handleTooManyErrors() {
		console.error('错误数量过多，采取保护措施');
		
		// 显示用户友好的错误提示
		uni.showModal({
			title: '系统繁忙',
			content: '系统暂时繁忙，请稍后再试',
			showCancel: false,
			success: () => {
				// 可以在这里添加重启应用或清理资源的逻辑
			}
		});
	}

	/**
	 * 包装异步函数，自动捕获错误
	 * @param {Function} fn 异步函数
	 * @param {string} context 上下文
	 */
	async wrapAsync(fn, context = 'Unknown') {
		try {
			return await fn();
		} catch (error) {
			this.handleError(`${context} Error`, error);
			throw error; // 重新抛出错误，让调用者处理
		}
	}

	/**
	 * 包装定时器，自动捕获错误
	 * @param {Function} fn 定时器函数
	 * @param {number} delay 延迟时间
	 * @param {string} context 上下文
	 */
	wrapTimer(fn, delay, context = 'Timer') {
		return setTimeout(() => {
			this.wrapAsync(fn, context);
		}, delay);
	}

	/**
	 * 获取错误统计
	 */
	getErrorStats() {
		return {
			errorCount: this.errorCount,
			maxErrors: this.maxErrors,
			lastErrorTime: this.lastErrorTime,
			isHandling: this.isHandling
		};
	}

	/**
	 * 重置错误计数
	 */
	resetErrorCount() {
		this.errorCount = 0;
		this.lastErrorTime = 0;

	}
}

// 创建单例实例
const errorHandler = new ErrorHandler();

export { errorHandler }; 